package com.xutianpeng.disk.user.service.impl;

import com.xutianpeng.disk.mybatis.entity.PtUserEntity;
import com.xutianpeng.disk.mybatis.flexigrid.PagingEntity;
import com.xutianpeng.disk.mybatis.flexigrid.TblResponseEntity;
import com.xutianpeng.disk.mybatis.ztree.ZtreeEntity;
import com.xutianpeng.disk.user.entity.SearchUserEntity;
import com.xutianpeng.disk.user.exeption.EmailRepeatException;
import com.xutianpeng.disk.user.exeption.MobileRepeatException;
import com.xutianpeng.disk.user.exeption.UserNameRepeatException;
import com.xutianpeng.disk.user.exeption.UserOccupyException;
import com.xutianpeng.disk.user.repository.UserDao;
import com.xutianpeng.disk.user.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

@Service
public class UserServiceImpl implements UserService {
    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Resource
    private UserDao userDao;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
    public List<PtUserEntity> queryUserList() {
        logger.info("查询所有用户列表");
        return userDao.queryUserList();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPassword(String[] userUuids) {
        if (userUuids == null || userUuids.length == 0) {
            logger.warn("重置密码时用户UUID数组为空");
            return;
        }

        logger.info("重置用户密码，用户UUID列表: {}", Arrays.toString(userUuids));
        userDao.resetPasswords(userUuids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setNewPassword(String userUuid, String newPassword) {
        if (!StringUtils.hasText(userUuid) || !StringUtils.hasText(newPassword)) {
            logger.error("设置新密码失败，用户UUID或新密码为空");
            throw new IllegalArgumentException("用户ID和新密码不能为空");
        }

        // 密码格式验证（至少8位，包含字母和数字）
        if (!Pattern.matches("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$", newPassword)) {
            logger.error("设置新密码失败，密码格式不符合要求");
            throw new IllegalArgumentException("密码格式不符合要求，至少8位并包含字母和数字");
        }

        logger.info("用户设置新密码，用户UUID: {}", userUuid);
        // 加密密码
        String encodedPassword = passwordEncoder.encode(newPassword);
        // 更新密码并清除重置标记
        userDao.updatePassword(userUuid, encodedPassword, 0);
    }

    @Override
    public boolean needResetPassword(String userUuid) {
        if (!StringUtils.hasText(userUuid)) {
            return false;
        }

        PtUserEntity user = userDao.queryUserInfoById(userUuid);
        return user != null && (user.getNeedResetPwd() == 1 || StringUtils.isEmpty(user.getPassword()));
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUserByIds(String ids) throws UserOccupyException {
        if (!StringUtils.hasText(ids)) {
            logger.warn("删除用户时传入的ID为空");
            return;
        }

        String[] idArray = ids.split(",");
        StringBuilder sb = new StringBuilder();

        // 检查用户是否关联角色
        for (String id : idArray) {
            String roleName = userDao.queryRoleListByUser(id);
            if (roleName != null) {
                sb.append(roleName).append(",");
            }
        }

        // 存在关联角色时抛出异常
        if (sb.length() > 0) {
            String roleNames = sb.substring(0, sb.length() - 1);
            logger.error("删除用户失败，用户关联角色: {}", roleNames);
            throw new UserOccupyException(roleNames);
        }

        // 执行删除操作
        for (String id : idArray) {
            userDao.deleteUserById(id);
            logger.info("删除用户成功，用户ID: {}", id);
        }
    }

    @Override
    public TblResponseEntity<PtUserEntity> queryUserInfoListByPage(SearchUserEntity entity, PagingEntity paging) {
        logger.info("分页查询用户列表，搜索条件: {}, 分页参数: {}", entity, paging);

        TblResponseEntity<PtUserEntity> responseEntity = new TblResponseEntity<>();
        Integer total = userDao.queryUserTotal(entity);
        responseEntity.setTotal(total);

        paging.deal(PtUserEntity.class, total);
        responseEntity.setPage(paging.getPage());

        List<PtUserEntity> rawRecords = userDao.queryUserInfoListByPage(entity, paging);
        responseEntity.setRawRecords(rawRecords);
        responseEntity.deal();

        logger.info("分页查询用户列表完成，总条数: {}", total);
        return responseEntity;
    }

    @Override
    public PtUserEntity queryUserInfoById(String userUuid) {
        if (!StringUtils.hasText(userUuid)) {
            logger.warn("查询用户信息时用户UUID为空");
            return null;
        }
        logger.info("查询用户信息，用户UUID: {}", userUuid);
        return userDao.queryUserInfoById(userUuid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyUserInfoById(PtUserEntity entity) throws EmailRepeatException, MobileRepeatException, UserNameRepeatException {
        if (entity == null || !StringUtils.hasText(entity.getUserUuid())) {
            logger.error("修改用户信息失败，用户实体或UUID为空");
            throw new IllegalArgumentException("用户信息不完整");
        }

        logger.info("修改用户信息，用户UUID: {}", entity.getUserUuid());

        // 校验邮箱唯一性
        List<PtUserEntity> entityList = userDao.queryUserInfoByEmail(entity);
        if (!entityList.isEmpty()) {
            logger.error("修改用户失败，邮箱已存在: {}", entity.getEmail());
            throw new EmailRepeatException("邮箱已被占用");
        }

        // 校验手机号唯一性
        entityList = userDao.queryUserInfoByMobile(entity);
        if (!entityList.isEmpty()) {
            logger.error("修改用户失败，手机号已存在: {}", entity.getMobile());
            throw new MobileRepeatException("手机号已被占用");
        }

        // 校验用户名唯一性
        entityList = userDao.queryUserInfoByUserName(entity);
        if (!entityList.isEmpty()) {
            logger.error("修改用户失败，用户名已存在: {}", entity.getUserName());
            throw new UserNameRepeatException("用户名已被占用");
        }

        userDao.modifyUserInfoById(entity);
        logger.info("修改用户信息成功，用户UUID: {}", entity.getUserUuid());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUserInfo(PtUserEntity entity) throws EmailRepeatException, MobileRepeatException, UserNameRepeatException {
        if (entity == null || !StringUtils.hasText(entity.getUserName()) || !StringUtils.hasText(entity.getPassword())) {
            logger.error("新增用户失败，用户名或密码为空");
            throw new IllegalArgumentException("用户名和密码不能为空");
        }

        logger.info("新增用户，用户名: {}", entity.getUserName());

        // 校验邮箱唯一性
        List<PtUserEntity> entityList = userDao.queryUserInfoByEmail(entity);
        if (!entityList.isEmpty()) {
            logger.error("新增用户失败，邮箱已存在: {}", entity.getEmail());
            throw new EmailRepeatException("邮箱已被占用");
        }

        // 校验手机号唯一性
        entityList = userDao.queryUserInfoByMobile(entity);
        if (!entityList.isEmpty()) {
            logger.error("新增用户失败，手机号已存在: {}", entity.getMobile());
            throw new MobileRepeatException("手机号已被占用");
        }

        // 校验用户名唯一性
        entityList = userDao.queryUserInfoByUserName(entity);
        if (!entityList.isEmpty()) {
            logger.error("新增用户失败，用户名已存在: {}", entity.getUserName());
            throw new UserNameRepeatException("用户名已被占用");
        }

        // 密码加密
        String encodedPassword = passwordEncoder.encode(entity.getPassword());
        entity.setPassword(encodedPassword);

        userDao.addUserInfo(entity);
        logger.info("新增用户成功，用户UUID: {}", entity.getUserUuid());
    }

    @Override
    public List<ZtreeEntity> queryRoleTreeListByUser(String userUuid) {
        if (!StringUtils.hasText(userUuid)) {
            logger.warn("查询用户角色树时用户UUID为空");
            return null;
        }

        logger.info("查询用户角色树，用户UUID: {}", userUuid);
        List<ZtreeEntity> ztreeEntityList = userDao.queryRoleTreeList();
        List<String> roleArray = userDao.queryRoleByUser(userUuid);

        // 标记用户已拥有的角色
        for (ZtreeEntity ztreeEntity : ztreeEntityList) {
            if (roleArray.contains(ztreeEntity.getId())) {
                ztreeEntity.setChecked(true);
            }
        }

        return ztreeEntityList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRoleRefUser(String userUuidArray, String roleUuidArray) {
        if (!StringUtils.hasText(userUuidArray)) {
            logger.warn("保存用户角色关联时用户UUID数组为空");
            return;
        }

        logger.info("保存用户角色关联，用户UUID数组: {}, 角色UUID数组: {}", userUuidArray, roleUuidArray);
        String[] userUuids = userUuidArray.split(",");
        String[] roleUuids = StringUtils.hasText(roleUuidArray) ? roleUuidArray.split(",") : new String[0];

        for (String userUuid : userUuids) {
            // 先删除原有关联
            userDao.deleteRoleByUser(userUuid);

            // 建立新关联
            for (String roleUuid : roleUuids) {
                userDao.insertRoleRefUser(userUuid, roleUuid);
                logger.info("建立用户角色关联，用户UUID: {}, 角色UUID: {}", userUuid, roleUuid);
            }
        }
    }

    @Override
    public PtUserEntity queryUserByUsername(String username) {
        if (!StringUtils.hasText(username)) {
            logger.warn("根据用户名查询用户时用户名为空");
            return null;
        }

        logger.info("根据用户名查询用户，用户名: {}", username);
        PtUserEntity queryEntity = new PtUserEntity();
        queryEntity.setUserName(username);
        List<PtUserEntity> users = userDao.queryUserInfoByUserName(queryEntity);
        return users.isEmpty() ? null : users.get(0);
    }

    @Override
    public boolean checkMobileExists(String mobile) {
        if (!StringUtils.hasText(mobile)) {
            return false;
        }

        PtUserEntity queryEntity = new PtUserEntity();
        queryEntity.setMobile(mobile);
        List<PtUserEntity> users = userDao.queryUserInfoByMobile(queryEntity);
        return !users.isEmpty();
    }

    @Override
    public boolean checkEmailExists(String email) {
        if (!StringUtils.hasText(email)) {
            return false;
        }

        PtUserEntity queryEntity = new PtUserEntity();
        queryEntity.setEmail(email);
        List<PtUserEntity> users = userDao.queryUserInfoByEmail(queryEntity);
        return !users.isEmpty();
    }

    @Override
    public boolean checkUsernameExists(String username) {
        if (!StringUtils.hasText(username)) {
            return false;
        }

        PtUserEntity queryEntity = new PtUserEntity();
        queryEntity.setUserName(username);
        List<PtUserEntity> users = userDao.queryUserInfoByUserName(queryEntity);
        return !users.isEmpty();
    }

    @Override
    public PtUserEntity getUserByUsername(String currentUsername) {
        return userDao.selectByUsername(currentUsername);
    }

}